package nc.tb.wf.ui;

import java.awt.Graphics;
import java.awt.Shape;
import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.List;

import org.jgraph.graph.CellHandle;
import org.jgraph.graph.CellView;
import org.jgraph.graph.CellViewRenderer;
import org.jgraph.graph.EdgeView;
import org.jgraph.graph.GraphConstants;
import org.jgraph.graph.GraphContext;
import org.jgraph.graph.PortView;

public class ActionEdgeView extends EdgeView
{
	public static transient ActionEdgeRenderer renderer = new ActionEdgeRenderer();

	public ActionEdgeView()
	{
		super();
	}

	public ActionEdgeView(Object cell)
	{
		super(cell);
		if(cell instanceof TransitionGraph){
			((TransitionGraph)cell).setView(this);
		}
	}
	@Override
	public CellViewRenderer getRenderer(){
		/*String strDesc = null;
		if(cell instanceof TransitionGraph){
			strDesc = ((TransitionGraph)cell).getDesc();
		}
		if(strDesc != null)
			renderer.setTips(strDesc);*/
		return renderer;
	}
	public void setSource(CellView sourceView) {
		setSource(sourceView,!isNewCreated());
	}
	private boolean isNewCreated(){
		if(cell instanceof TransitionGraph){
			List points = GraphConstants.getPoints(((TransitionGraph)cell).getAttributes());
			return points == null || points.isEmpty();
		}else{
			return false;
		}
		
	}
	/**
	 * Sets the <code>sourceView</code> of the edge.
	 */
	public void setSource(CellView sourceView,boolean pointFirst) {
		sourceParentView = null;
		source = sourceView;
		if (!pointFirst && source != null)
			points.set(0, source);
		else
			points.set(0, getPoint(0));
		invalidate();
	}
	public void setTarget(CellView targetView) {
		setTarget(targetView,!isNewCreated());
	}
/**
	 * Sets the <code>targetView</code> of the edge.
	 */
	public void setTarget(CellView targetView,boolean pointFirst) {
		target = targetView;
		targetParentView = null;
		int n = points.size() - 1;
		if(!pointFirst && target != null)
			points.set(n, target);
		else
			points.set(n, getPoint(n));
		invalidate();
	}
	/**
	 * Returns the cached points for this edge.
	 */
	public Point2D getPoint(int index) {
		Object obj = points.get(index);
		if (index == 0 && sourceParentView != null) {
			return sourceParentView.getPerimeterPoint(this,
					getCenterPoint(sourceParentView),
					getNearestPoint(index == 0));
		} else if (index == getPointCount() - 1 && targetParentView != null) {
			return targetParentView.getPerimeterPoint(this,
					getCenterPoint(targetParentView),
					getNearestPoint(index == 0));
		} else if (obj instanceof PortView)
			// Port Location Seen From This Edge
			return ((PortView) obj).getLocation(this,
					getNearestPoint(index == 0));
		else if (obj instanceof CellView) {
			// Should not happen
			Rectangle2D r = ((CellView) obj).getBounds();
			return new Point2D.Double(r.getX(), r.getY());
		} else if (obj instanceof Point2D)
			// Regular Point
			return (Point2D) obj;
		return null;
	}
	/**
	 * Returns the shape of the view according to the last rendering state
	 */
	/*public Shape getShape() {
		if (sharedPath != null)
			return sharedPath;
		else {
			return sharedPath = (GeneralPath) renderer.createShape();
		}
	}*/
	class ActionEdgeHandle extends EdgeHandle
	{
		public ActionEdgeHandle(EdgeView edge, GraphContext ctx)
		{
			super(edge, ctx);
		}

		public void paint(Graphics g)
		{
			super.paint(g);
			edge.sharedPath = null;
			edge.update(graph.getGraphLayoutCache());
//			invalidate();
			
		}
	}

	@Override
	public CellHandle getHandle(GraphContext context)
	{
		return new ActionEdgeHandle(this, context);
	}
}
